New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: Add StaticStates wrapper #377
chore: Add StaticStates wrapper #377
Conversation
Test summaryRun details
View run in Cypress Dashboard ➡️ This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard |
Thoughts on loading |
@anicholls that makes sense to me. In the icon button PR, i had the states as a last story after seeing all the defaults! |
.storybook/config.js
Outdated
const prefixFn = pipe( | ||
prefix('welcome-', '0'), | ||
prefix('getting-started', '0'), | ||
prefix('tokens-', '1'), | ||
prefix('components-', '2'), | ||
prefix('components-', '3'), | ||
prefix('states', '4'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works, but I think we may want to do this separately from this calculation. This is specifically meant to target the prefix from the categories at the top level of storybook. I believe this could result in some unexpected edge cases for something like a story named Tokens|Foo/Bar/States
. I would suggest doing a separate check after the number prefix has already been added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function replaced another function that only handled top-level categories. The input of that function was something like ['Welcome', 'Tokens', 'Components']
, but I also needed to make sure "Getting Started" was the first item under "Welcome" so that Storybook picked it as the default page. Numbers were chosen because sorting alphabetically ensures numbers rank higher than letters, so '0first' will come before 'first'. Also numbers are easy for us to understand in terms of "ranking".
This function is definitely a hack, but the intent is to be powerful enough to handle sorting on a global level while still being easy enough to add new sorting rules. I actually think adding prefix('states', '3')
before the prefix('components-', '3')
would accomplish the same goal without introducing a new sorting hierarchy ('3' would be prefixed for having 'states' in the storyname first, then '3' would be prefixed first for being in the "Components" category).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I retract the 3
. It has to be a 4
to not be the first story in Components
... Perhaps not very intuitive
I just realized that we have the same problem with this that we did when we tried to add a @NicholasBoll I think this is probably okay to go in as is, but we really need to look at re-writing the |
Agreed. I think the ideal implementation is using a Context where a Provider (we originally called it We tried it in the For a better developer experience, I think we'd take on the maintenance burden of maintaining our own styled wrapper to make it seamless. |
After talking with @anicholls, it is possible to use our I opted out of having the boolean parameter part of |
const prefix = (phrase, prefix) => value => (value.indexOf(phrase) > -1 ? prefix + value : value); | ||
const prefix = (phrase, prefix) => (/** @type {string} */ value) => { | ||
const index = value.indexOf(phrase); | ||
return index > -1 ? value.substr(0, index) + prefix + value.substr(index) : value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change allows for multi-tier sorting instead of a global sorting. For example, "Welcome" is the category and "getting-started" is the item. The below will produce a string like:
"0welcome--agetting-started"
Since the "a" is now added before "getting-started" instead of before "welcome", it allows sorting to be local to other items. Lowercase letters should be used in multi-tier sorting so it flows naturally with other items without disrupting them. For example, numbers are always before lowercase letters in ASCII. So even if you add a '9', it will sort first rather than the desired last which is why z
is used below
.replace(/^:/, '&:') // handle shorthand like ":focus" | ||
.replace(/,(\s+):/g, ',$1&:') // handle selectors like ":focus, :hover" | ||
.replace(/:(focus|hover|active)/g, '.$1') | ||
.replace(/\[data\-whatinput="?(mouse|touch|keyboard|pointer)"?]/g, '[data-whatinput="noop"]'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disables the InputProvider
style overrides
function styled<Props>(node: any) { | ||
return (...args: Interpolation<Props>[]) => { | ||
const newArgs: Interpolations = args.map( | ||
interpolation => (props: Props & {theme: CanvasTheme; direction: ContentDirection}) => { | ||
interpolation => (props: Props & {theme: CanvasTheme & {_staticStates?: boolean}}) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not adding _staticStates
to CanvasTheme
keeps it private
Changes requested are now outdated
Fixes: #375
This is separating the work in #271
This creates a wrapper for stories to allow for treating pseudo-selectors like
:hover
or:focus
as static states that are controllable as classes rather than the default pseudo-selectors.For example, this is now a valid story:
This code will render a button with focus styling always applied. This is useful for enumerating states for design or validating states in visual regression tests.
To enable this functionality, Components must use the Canvas-kit
styled
function instead of the one from Emotion. The canvas-kitstyled
function also seamlessly handles a fallback to default theme and RTL support out-of-the-box.